package com.apes.fn.business.fixedLoss.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.business.fixedLoss.modle.FixedLossLimitDetail;
import com.apes.fn.business.fixedLoss.modle.FixedLossLimitPerMonth;
import com.apes.fn.business.fixedLoss.repository.FixedLossLimitDetailRepository;
import com.apes.fn.business.fixedLoss.repository.FixedLossLimitPerMonthRepository;
import com.apes.fn.business.fixedLoss.repository.LossQuotationDao;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.Arith;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName FixedLossLimitDetailService
 * @Author wsj
 * @Date 2021/5/7 18:35
 * @description 定损额度变化明细  业务层
 */
@Service("fixedLossLimitDetailService")
public class FixedLossLimitDetailService extends DomainService {
    @Autowired
    private FixedLossLimitDetailRepository detailRepository;
    @Autowired
    private FixedLossLimitPerMonthRepository fixedLossLimitPerMonthRepository;
    @Autowired
    private LossQuotationDao lossQuotationDao;

    public void insertFixedLossLimit(SimpleRequest request) {
        //获取当天车险销售数据
        JSONObject param = request.getJO();
        JSONObject parameter = new JSONObject();
        parameter.put("DATE", param.getDate("taskDate"));
        JSONArray dataArray = lossQuotationDao.queryInsuranceSale(parameter);
        if (dataArray.size() >0) {
            for (int i = 0,len = dataArray.size(); i < len; i++) {
                JSONObject saleData = dataArray.getJSONObject(i);
                double insuranceAmount = saleData.getDoubleValue("INSURANCE_AMOUNT");
                String deptId = saleData.getString("DEPT_ID");
                Dept dept = SpringManager.getBean(DeptRepository.class).findOne(deptId);
                if (Objects.isNull(dept)) {
                    throw new RuntimeException(deptId + "该部门编码无对应数据!!!");
                }
                FixedLossLimitDetail detail = detailRepository.findAll(
                        JpaDsl.toCriteriaByEq("dept.id",dept.getId(),"statisticDate",saleData.getDate("STATISTIC_DATE"))
                ).stream().findFirst().orElse(null);
                if (Objects.isNull(detail)) {
                    detail = new FixedLossLimitDetail();
                }
                if (insuranceAmount > 0) {
                    Map map = MapUtil.mapper("OPERATION", dept.getCompany().getParty().getCorporate().getOperation().getId(),
                            "DEPT_ID", deptId,"conditionStrategyId","BF_CZB","SYS_RQ", new Date());
                    Object object = null;
                    try {
                        object = this.invoke("condition.execConditionStrategy", map);
                    } catch (Exception e) {
                        throw new RuntimeException(e.getMessage()+",门店编码:"+map.get("DEPT_ID"));
                    }
                    JSONObject result = new JSONObject(Objects.requireNonNull(MapUtil.mapped(object)));
                    double transformQuota = Arith.mul(insuranceAmount, result.getDoubleValue("T001"));
                    detail.setTransformQuota(transformQuota);
                    detail.setCreateDate(new Date());
                }
                detail.setDept(dept);
                detail.setStatisticDate(saleData.getDate("STATISTIC_DATE"));
                detail.setInsuranceAmount(insuranceAmount);
                detail.setQuotaUsed(saleData.getDoubleValue("SALE_AMOUNT"));
                detailRepository.save(detail);
            }
        }
        EntityManager entityManager = SpringManager.getBean(EntityManager.class);
        Query query = entityManager.createNativeQuery("{call SUM_DEPT_QUOTA(?)}").setParameter(1,param.getDate("taskDate"));
        query.executeUpdate();
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        try {
            insertFixedLossLimitPerMonth(formatter.parse(param.getString("taskDate")));
        } catch (ParseException e) {
            throw new RuntimeException("时间格式转换失败");
        }
    }

    /**
     * 生成定损额度(月)
     * @param taskDate
     */
    public void insertFixedLossLimitPerMonth(Date taskDate) {
        LocalDate localDate = DateUtil.UDateToLocalDate(taskDate);
        Date firstDayOfMonth = DateUtil.ULocalDateToDate(localDate.with(TemporalAdjusters.firstDayOfMonth()));
        Date lastDayOfMonth = DateUtil.ULocalDateToDate(localDate.with(TemporalAdjusters.lastDayOfMonth()));
        JSONObject parameter = new JSONObject();
        parameter.put("firstDayOfMonth", firstDayOfMonth);
        parameter.put("lastDayOfMonth", lastDayOfMonth);
        parameter.put("taskDate", taskDate);
        JSONArray details = lossQuotationDao.queryFixedLossLimitDetail(parameter);
        details.forEach(detail->{
            JSONObject object = (JSONObject) detail;
            FixedLossLimitPerMonth fixedLossLimitPerMonth = fixedLossLimitPerMonthRepository.findOne(localDate.getYear()+""+localDate.getMonthValue()+object.getString("DEPT_ID"));
            if (fixedLossLimitPerMonth == null) {
                fixedLossLimitPerMonth = new FixedLossLimitPerMonth();
                fixedLossLimitPerMonth.setId(localDate.getYear()+""+localDate.getMonth()+object.getString("DEPT_ID"));
                fixedLossLimitPerMonth.setDept(SpringManager.getBean(DeptRepository.class).findOne(object.getString("DEPT_ID")));
            }
            fixedLossLimitPerMonth.setStatisticDate(taskDate);
            fixedLossLimitPerMonth.setInsuranceAmount(object.getDoubleValue("INSURANCE_AMOUNT"));
            fixedLossLimitPerMonth.setUseQuota(object.getDoubleValue("USED_QUOTA"));
            fixedLossLimitPerMonth.setConvertQuota(object.getDoubleValue("TRANSFORM_QUOTA"));
            fixedLossLimitPerMonth.setAdditionalQuota(object.getDoubleValue("TARGET_AMOUNT"));
            fixedLossLimitPerMonth.setTotalQuota(Arith.add(object.getDoubleValue("TARGET_AMOUNT"),object.getDoubleValue("TRANSFORM_QUOTA")));
            fixedLossLimitPerMonth.setSurplusQuota(Arith.sub(fixedLossLimitPerMonth.getTotalQuota(),fixedLossLimitPerMonth.getUseQuota()));
            fixedLossLimitPerMonth.setExpiredQuota(object.getDoubleValue("OVERDUE_AMOUNT"));

            //获取上月额度
            FixedLossLimitPerMonth perMonth = fixedLossLimitPerMonthRepository.findOne(localDate.getYear() + "" + (localDate.getMonthValue() - 1) + object.getString("DEPT_ID"));
            if (perMonth != null && perMonth.getSurplusQuota() > 0) {
                fixedLossLimitPerMonth.setLastMonthSurplusQuota(perMonth.getSurplusQuota());
            }
            fixedLossLimitPerMonth.setMakeUpFee(0);
            if (fixedLossLimitPerMonth.getSurplusQuota() < 0) {
                Map map = MapUtil.mapper(
                        "OPERATION", fixedLossLimitPerMonth.getDept().getCompany().getParty().getCorporate().getOperation().getId(), "COMPANY_ID", fixedLossLimitPerMonth.getDept().getCompany().getId(), "SYS_RQ", taskDate, "conditionStrategyId", "DS02"
                );
                Object obj = null;
                try {
                    obj = this.invoke("condition.execConditionStrategy", map);
                }catch (Exception e){
                    throw new RuntimeException("取补还定损管理费率策略出错,请联系后台人员处理!!!公司id:"+fixedLossLimitPerMonth.getDept().getCompany().getId());
                }
                JSONObject result = new JSONObject(MapUtil.mapped(obj));

                JSONObject jo = new JSONObject(Objects.requireNonNull(MapUtil.mapped(this.invoke("condition.execConditionStrategy", MapUtil.mapper("OPERATION", fixedLossLimitPerMonth.getDept().getCompany().getParty().getCorporate().getOperation().getId(),
                        "DEPT_ID", fixedLossLimitPerMonth.getDept().getId(), "conditionStrategyId", "BF_CZB", "SYS_RQ", new Date())))));
                double transformQuota=fixedLossLimitPerMonth.getSurplusQuota();
                if (jo.getDoubleValue("T001") != 0) {
                    transformQuota = Arith.div(fixedLossLimitPerMonth.getSurplusQuota(), jo.getDoubleValue("T001"),2);
                    fixedLossLimitPerMonth.setPayPremium(Arith.div(fixedLossLimitPerMonth.getSurplusQuota(), jo.getDoubleValue("T001")));
                }
                fixedLossLimitPerMonth.setMakeUpFee(transformQuota * result.getDoubleValue("A021"));
            }
            //月底
//            if (localDate.with(TemporalAdjusters.lastDayOfMonth()).equals(LocalDate.now())) {
//                if (fixedLossLimitPerMonth.getSurplusQuota() < 0) {
//                    //生成费用单
//                    ExpenseItem expenseItem = new ExpenseItem();
//                    expenseItem.setAmount(fixedLossLimitPerMonth.getSurplusQuota());
//                    expenseItem.setExpenseType(SpringManager.getBean(ExpenseTypeRepository.class).findOne("B10"));
//                    expenseItem.setCalculateDate(new Date());
//                    expenseItem.setPeriodStart(firstDayOfMonth);
//                    expenseItem.setPeriodEnd(lastDayOfMonth);
//                    expenseItem.setRemark(String.format("日结定损特权额度产生！[%s]", fixedLossLimitPerMonth.getId()));
//                    expenseItem.setCompany(fixedLossLimitPerMonth.getDept().getCompany());
//                    List<ExpenseItem> expenseItemList=new ArrayList<>();
//                    expenseItemList.add(expenseItem);
//
//                    Expense expense = new Expense();
//                    expense.setCompany(fixedLossLimitPerMonth.getDept().getCompany());
//                    expense.setAmtTotal(expenseItemList.stream().mapToDouble(ExpenseItem::getAmount).sum());
//                    expense.setState("approve");
//                    expense.setApproveDate(new Date());
//                    expense.setExpenseItems(expenseItemList);
//                    SpringManager.getBean(ExpenseRepository.class).saveAndFlush(expense);
//                }
//            }
            fixedLossLimitPerMonthRepository.saveAndFlush(fixedLossLimitPerMonth);
        });

    }

}
